interface ErrorJson {
    message: string
    name: string
    description: string
    number: string
    fileName: string
    lineNumber: string
    columnNumber: string
    stack: string
    config: string
    code: string
}

interface ErrorInstance extends Error {
    config: any
    code?: string
    request: any
    response: any
    isAxiosError: boolean
    toJSON: () => ErrorJson
}

function enhanceError(error: ErrorInstance, config: any, code: string, request = null, response = null): ErrorInstance {
    error.config = config;
    if (code) {
        error.code = code;
    }

    error.request = request;
    error.response = response;
    error.isAxiosError = true;

    error.toJSON = function toJSON() {
        return {
            // Standard
            message: this.message,
            name: this.name,
            // Microsoft
            description: this.description,
            number: this.number,
            // Mozilla
            fileName: this.fileName,
            lineNumber: this.lineNumber,
            columnNumber: this.columnNumber,
            stack: this.stack,
            // Axios
            config: this.config,
            code: this.code
        };
    };
    return error;
};

/**
 * 抛出错误
 * @param message 错误消息
 * @param config 配置
 * @param code 错误码
 * @param request 
 * @param response 
 */
export default function createError(message: string, config: any, code: any, request?: any, response?: any) {
    const error = new Error(message);
    return enhanceError(error as ErrorInstance, config, code, request, response);
};
